import math
import time
import numpy as np
from PIL import ImageFont, Image, ImageDraw
from const.byte_order_enum import ByteOrder
from const.font_mode_enum import FontMode
from dto.param import CANVAS_SIZE


def init_font_array(font_size):
    image_font = ImageFont.truetype('simsun', size=(font_size - 1))
    # paint and write font
    with (Image.new('L', (font_size, font_size), 0)) as image:
        ImageDraw.Draw(image).text((1, 1), chr(ord('路')), font=image_font, fill=255)

        # display the img by image.show(), save the image by image.save('c.png')
        # convert to array from image
        return np.array(image)


def ceil_division(a, b):
    # 普通除法，结果为浮点数
    result = a / b
    return a // b if result.is_integer() else math.ceil(result)


def do_draw_point(canvas, x, y, color='black', radius=5):
    """在Canvas上绘制一个点

    参数:
    canvas -- Tkinter的Canvas对象
    x, y -- 点的坐标
    color -- 点的颜色（默认为黑色）
    radius -- 点的半径（以像素为单位），通过控制半径的大小可以控制点的大小，但过大会更像是一个圆
    """
    canvas.create_oval(x - radius, y - radius, x + radius, y + radius, fill=color, outline='')


class Draw:
    def __init__(self, ):
        # Thread status
        self.is_running = 1

    def draw(self, canvas, mode, font_size, byte_order, color, bg_color):
        image_array = init_font_array(font_size)
        canvas.configure(bg=bg_color)

        while 1:
            canvas.delete("all")

            if mode == FontMode.V_FIRST_TOP_BOTTOM__LAST_LEFT_RIGHT.name.lower():
                bytes_of_height = ceil_division(font_size, 8)
                for i in range(font_size):
                    for j in range(bytes_of_height):
                        if byte_order == ByteOrder.SMALL.name.lower():
                            for bit_in_byte in range(8 if (j + 1) * 8 <= font_size else (font_size % 8)):
                                bit = image_array[j * 8 + bit_in_byte, i]
                                if bit:
                                    x_pos = CANVAS_SIZE // font_size * i
                                    y_pos = CANVAS_SIZE // font_size * (j * 8 + bit_in_byte)
                                    do_draw_point(canvas, x_pos, y_pos, color, radius=2)
                                    time.sleep(0.05)
                                if self.is_running != 1:
                                    return None
                        else:
                            size_ = 8 if (j + 1) * 8 <= font_size else (font_size % 8)
                            for bit_in_byte in range(size_ - 1, -1, -1):
                                bit = image_array[j * 8 + bit_in_byte, i]
                                if bit:
                                    x_pos = CANVAS_SIZE // font_size * i
                                    y_pos = CANVAS_SIZE // font_size * (j * 8 + bit_in_byte)
                                    do_draw_point(canvas, x_pos, y_pos, color, radius=2)
                                    time.sleep(0.05)
                                if self.is_running != 1:
                                    return None
            elif mode == FontMode.V_FIRST_LEFT_RIGHT__LAST_TOP_BOTTOM.name.lower():
                # TODO
                time.sleep(0.01)
                if self.is_running != 1:
                    return None
            elif mode == FontMode.H_FIRST_TOP_BOTTOM__LAST_LEFT_RIGHT.name.lower():
                # TODO
                time.sleep(0.01)
                if self.is_running != 1:
                    return None
            elif mode == FontMode.H_FIRST_LEFT_RIGHT__LAST_TOP_BOTTOM.name.lower():
                # TODO
                time.sleep(0.01)
                if self.is_running != 1:
                    return None
            else:
                return None

    def start(self):
        self.is_running = 1

    def stop(self):
        self.is_running = 0
